<?php

class Item extends CActiveRecord {

    public static $TYPES = array();

    protected $_oldName;

    protected $_oldType;

    public function init() {
        $this->_initTypes();
    }

    protected static function _initTypes() {
        self::$TYPES = array(Yii::t('crm', 'Operation'), Yii::t('crm', 'Gruppe'), Yii::t('crm', 'Rolle'));
    }

    public function validate($scenario='',$attributes=null) {
        $parentValidation = parent::validate($scenario, $attributes);
        if(strtolower($scenario) === 'update' && (int)$this->type !== $this->getOldType()) {
            $this->addError('type', Yii::t('crm', 'Der Typ darf nachträglich nich mehr geändert werden!'));
            return false;
        }
        return $parentValidation;
    }

    public function getOldType() {
        return $this->_oldType;
    }

    public function setOldType($oldType) {
        $this->_oldType = (int)$oldType;
    }

    public function getOldName() {
        return $this->_oldName;
    }

    public function setOldName($oldName) {
        $this->_oldName = (string)$oldName;
    }

    public function afterSave() {
        parent::afterSave();
        if($this->getOldName() !== $this->name) {
            $this->model()->updateByPk($this->getOldName(), array("name"=>$this->name));
        }
    }

    /**
     * Returns the static model of the specified AR class.
     * @return CActiveRecord the static model class
     */
    public static function model($className=__CLASS__) {
        self::_initTypes();
        return parent::model($className);
    }

    public function getType($index) {
        return self::$TYPES[(int)$index];
    }

    public function getTypes() {
        return self::$TYPES;
    }

    /**
     * @return string the associated database table name
     */
    public function tableName() {
        return 'rbac_items';
    }

    public function safeAttributes() {
        parent::safeAttributes();
        return array('name','type','description','bizrule','data');
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules() {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
                array('name, type, description', 'required'),
                array('type', 'numerical', 'integerOnly'=>true),
                array('name', 'length', 'max'=>50),
                array('description', 'length', 'max'=>255),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations() {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
        );
    }

    public function findAssignmentsForUserById($userId) {
        if((bool)$userId) {
            $auth = Yii::app()->authManager;
            /**
             * will fetch all roles to the user
             */
            $roles = $auth->getAuthItems(2,$userId);
            $r = array();
            foreach($roles as $i=>$role) {
                $currentRole = $role->name;
                $tasks = $auth->getItemChildren($currentRole);
                $r[$i] = $currentRole;
                $r[$i] = array();
                foreach($tasks as $j=>$task) {
                    $currentTask = $task->name;
                    $operations = $auth->getItemChildren($currentTask);
                    $r[$i][$j] = $currentTask;
                    $r[$i][$j] = array();
                    foreach($operations as $k=>$operation) {
                        $currentOperation = $operation->name;
                        $r[$i][$j][$k] = $currentOperation;
                    }
                }
            }
            return $r;
        }
        return null;
    }

    public function findNotAssignedRolesByUser($userId) {
        if((bool)$userId) {
            $cr = new CDbCriteria();
            $cr->select = 'name,type,description';
            $cr->addCondition('type=:type');
            $cr->params = array(':type' => 2);
            $cr->order = 'name ASC';
            $roles = $this->findAll($cr);
            if($roles) {
                $assignedRoles = $this->findAssignedRolesByUser($userId);
                $finalRoles = array();
                foreach($roles as $notAssignedRole) {
                    $exists = false;
                    foreach($assignedRoles as $assignedRole) {
                        if($notAssignedRole['name'] === $assignedRole['name']) {
                            $exists = true;
                        }
                    }
                    if(false === $exists) {
                        $finalRoles[] = $notAssignedRole;
                    }
                }
                return $finalRoles;
            }
        }
        return array();
    }

    public function findNotAssignedOperationsByTask($taskName) {
        if(!empty ($taskName)) {
            $cr = new CDbCriteria();
            $cr->select = 'name,type,description';
            $cr->addCondition('type=:type');
            $cr->params = array(':type' => 0);
            $cr->order = 'name ASC';
            $operations = $this->findAll($cr);
            if($operations) {
                $assignedOperations = $this->findAssignedOperationsByTask($taskName);
                $finalTasks = array();
                foreach($operations as $notAssignedOperations) {
                    $exists = false;
                    foreach($assignedOperations as $assignedOperation) {
                        if($notAssignedOperations['name'] === $assignedOperation['name']) {
                            $exists = true;
                        }
                    }
                    if(false === $exists) {
                        $finalTasks[] = $notAssignedOperations;
                    }
                }
                return $finalTasks;
            }
        }
        return array();
    }

    public function findNotAssignedTasksByRole($roleName) {
        if(!empty ($roleName)) {
            $cr = new CDbCriteria();
            $cr->select = 'name,type,description';
            $cr->addCondition('type=:type');
            $cr->params = array(':type' => 1);
            $cr->order = 'name ASC';
            $tasks = $this->findAll($cr);
            if($tasks) {
                $assignedTasks = $this->findAssignedTasksByRole($roleName);
                $finalTasks = array();
                foreach($tasks as $notAssignedTasks) {
                    $exists = false;
                    foreach($assignedTasks as $assignedTask) {
                        if($notAssignedTasks['name'] === $assignedTask['name']) {
                            $exists = true;
                        }
                    }
                    if(false === $exists) {
                        $finalTasks[] = $notAssignedTasks;
                    }
                }
                return $finalTasks;
            }
        }
        return array();
    }

    public function findAssignedTasksByRole($roleName) {
        if(!empty($roleName)) {
            $cr = new CDbCriteria();
            $cr->select = 'name,type,description';
            $cr->join = 'INNER JOIN ' . ItemChildren::model()->tableName() . ' ON name = child';
            //$cr->join = 'INNER JOIN ' . Assignments::model()->tableName() . ' ON name=itemname';
            $cr->addCondition('type=:type');
            $cr->addCondition('parent=:parent');
            $cr->params = array(':type' => 1, ':parent' => $roleName);
            $operations = $this->findAll($cr);
            if($operations) {
                return $operations;
            }
        }
        return array();
    }

    public function findAssignedOperationsByTask($taskName) {
        if(!empty($taskName)) {
            $cr = new CDbCriteria();
            $cr->select = 'name,type,description';
            $cr->join = 'INNER JOIN ' . ItemChildren::model()->tableName() . ' ON name = child';
            //$cr->join = 'INNER JOIN ' . Assignments::model()->tableName() . ' ON name=itemname';
            $cr->addCondition('type=:type');
            $cr->addCondition('parent=:parent');
            $cr->params = array(':type' => 0, ':parent' => $taskName);
            $operations = $this->findAll($cr);
            if($operations) {
                return $operations;
            }
        }
        return array();
    }

    public function findAssignedRolesByUser($userId) {
        if((bool)$userId) {
            $cr = new CDbCriteria();
            $cr->select = 'name,type,description';
            $cr->join = 'INNER JOIN ' . Assignments::model()->tableName() . ' ON name=itemname';
            $cr->addCondition('type=:type');
            $cr->addCondition('userid=:userid');
            $cr->params = array(':type' => 2, ':userid' => $userId);
            $roles = $this->findAll($cr);
            if($roles) {
                return $roles;
            }
        }
        return array();
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels() {
        return array(
                'name' => Yii::t('crm', 'Name'),
                'type' => Yii::t('crm', 'Typ'),
                'description' => Yii::t('crm', 'Beschreibung'),
                'bizrule' => Yii::t('crm', 'Business - Logik'),
                'data' => Yii::t('crm', 'Daten'),
        );
    }
}